import React, {Component} from 'react';
import classNames from 'classnames';
import withStyles from 'material-ui/styles/withStyles';
import {Helmet} from 'react-helmet';
import LinearProgress from 'material-ui/Progress/LinearProgress';

import Typography from 'material-ui/Typography/Typography';
import Confirm from './comps/Confirm';
import Question from './comps/Question';
import CoverImage from 'react-components/src/CoverImage';
import Slide from 'material-ui/transitions/Slide';
import Fade from 'material-ui/transitions/Fade';

import illustrator from 'assets/home_illustrator.png';
import introThumbnail from 'assets/intro-thumbnail.jpg';
import filmThumbnail from 'assets/film-thumbnail.jpg';
import favorite from 'assets/favorite.jpg';
import sortBy from 'lodash/sortBy';

import text from './data/text.json';
import Dialog from './comps/Dialog';
import Article from './comps/Article';

const isCellular = (
  (navigator.connect || navigator.mozConnection || navigator.webkitConnection || {})
    .type === 'cellular'
);


const style = ({palette, breakpoints, mixins, spacing: {unit}}) => ({
  '@global': {
    html: {
      background: 'linear-gradient(to top, #c3463d, 35%, #ec6f63)',
      backgroundAttachment: 'fixed',
      WebkitFontSmoothing: 'antialiased',
      MozOsxFontSmoothing: 'grayscale'
    },
    body: {
      margin: 0,
    }
  },
  root: {
    position: 'relative',
    display: 'flex',
    flexDirection: 'column',
    width: '100%',
    minWidth: 350,
    minHeight: '100vh',
    boxSizing: 'border-box',
    maxWidth: breakpoints.values.md,
    marginRight: 'auto',
    marginLeft: 'auto',
    paddingTop: unit*2,
    paddingBottom: unit*2,
    ...mixins.gutters({})
  },
  toolbar: {
    boxSizing: 'border-box',
    width: '100%',
    maxWidth: breakpoints.values.md,
    marginRight: 'auto',
    marginLeft: 'auto'
  },
  video: {
    width: '100%'
  },
  listWrap: {
    display: 'flex',
    flexGrow: 1,
    flexDirection: 'column',
    justifyContent: 'space-around'
  },
  list: {
    paddingBottom: '25%',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
    '& > *': {
      width: 240
    }
  },
  illustrator: {
    position: 'fixed',
    minWidth: 420,
    height: '75vh',
    left: '-20%',
    right: '-20%',
    bottom: '-20%',
    marginLeft: 'auto',
    marginRight: 'auto',
    zIndex: -1
  },
  title: {
    fontFamily: 'FZXSHK',
    color: '#fff',
    fontSize: '2.4rem',
    lineHeight: 1.2,
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'stretch',
    flexGrow: 0,
    width: '100%',
    maxWidth: 480,
    marginLeft: 'auto',
    marginRight: 'auto',
    marginBottom: unit *2,
  },
  subtitle: {
    flexDirection: 'row',
    fontSize: '1.35rem',
    lineHeight: 1.5,
    '& > *': {
      flexBasis: '47.5%',
    },
    [breakpoints.up('sm')]: {
      fontSize: '1.75rem',
      // flexDirection: 'row'
    }
  },
  titleLine: {
    display: 'inline-flex',
    justifyContent: 'space-between',
    width: '100%'
  }
})


@withStyles(style)
class App extends Component {
  state = {
    videoIntro: {},
    videoFilm: {},
    fonts: [],
    showTitle: false,
    wiki: null,
    questions_inc: [],
    questions_rnd: []
  };


  componentWillMount() {
    this.fetchingQuestions = fetch(`${__webpack_public_path__}questions.json`, {cache: "reload"})
      .then(res => res.json())
      .then(({ include, random }) => {
        this.setState({ questions_inc: include, questions_rnd: random });
        this.fetchingQuestions = null;
      });

    fetch(`${__webpack_public_path__}wiki.json`, {cache: "reload"})
      .then(res => res.json())
      .then(wiki => this.setState({wiki}));

    fetch(`${__webpack_public_path__}profile.json`, {cache: "reload"})
      .then(res => res.json())
      .then(({['video-introduce']: videoIntro, ['video-film']: videoFilm, fonts, wxAppid, url}) => {
        this.setState({videoIntro, videoFilm, fonts});
        if (typeof wx === 'object') {
          fetch('https://www.mycuo.com/api/wechat/jsapi_sign')
            .then(res => res.json())
            .then(({success, signature, timestamp, noncestr}) => {
              if (success) {
                wx.ready(() => {
                  console.log('wechat jsapi ready')
                  wx.onMenuShareTimeline({
                    title: text['app-title'],
                    link: `https:${url}`,
                    imgUrl: `https:${favorite}`
                  });

                  wx.onMenuShareAppMessage({
                    title: text['app-title'],
                    desc: text['app-subtitle'],
                    link: `https:${url}`,
                    imgUrl: `https:${favorite}`
                  });
                });

                wx.config({
                  appId: wxAppid,
                  nonceStr: noncestr,
                  signature, timestamp,
                  jsApiList: [
                    'onMenuShareTimeline',
                    'onMenuShareAppMessage'
                  ]
                });

              }
            })
        }
      });
  }

  componentDidMount() {
    setTimeout(() => this.setState({showTitle: true}), 500);
  }


  getQuestions = (size) => {
    if (this.fetchingQuestions)
      return this.fetchingQuestions.then(() => this.getQuestions(size));

    const { questions_inc, questions_rnd } = this.state;

    const rnd = sortBy(questions_rnd, Math.random)
    const questions = sortBy(questions_inc.concat(rnd).slice(0, size), Math.random);

    return Promise.resolve(questions);
  };

  checkAnswer = (questionId, answerId) => {
    const { questions_inc, questions_rnd } = this.state;

    const question = questions_inc.concat(questions_rnd).find(q => q.id === questionId);
    const correctAnswer = question.answers.find(q => q.isCorrect) || question.answers[0];

    return Promise.resolve({
      isCorrect: answerId === correctAnswer.id,
      correctAnswer: correctAnswer.id
    })
  };

  render() {
    const {
      videoFilm,
      videoIntro,
      fonts,
      showTitle,
      wiki
    } = this.state;

    const classes = this.props.classes;


    return (
      <div className={classes.root}>
        <Helmet>
          <title>{text['app-name']}</title>
          <link rel="shortcut icon" type="image/jpg" href={favorite}/>
          {fonts.map((font, index) => (
            <link key={`fonts:${index}`} href={font.src} rel="stylesheet" />
          ))}
        </Helmet>

        <Typography type="headline" className={classNames(classes.title, classes.subtitle)}>
          {text['app-subtitle'].split('\n').map((line, lIndex) => (
            <div key={`line:${lIndex}`} className={classes.titleLine}>
              {line.split('').map((letter, index, lineLetters) => (
                <Fade
                  key={`word:${index}`}
                  in={showTitle}
                  onEntering={elem => {
                    elem.style.transitionDelay = 100 * (index + lIndex *lineLetters.length) + 'ms';
                  }}
                >
                  <span>{letter}</span>
                </Fade>
              ))}
            </div>
          ))}
        </Typography>

        <Typography type="title" className={classes.title}>
          {text['app-title'].split('\n').map((line, lIndex) => (
            <div key={`title-line:${lIndex}`} className={classes.titleLine}>
              {line.split('').map((letter, index, lineLetters) => (
                <Fade
                  key={`title-word:${index}`}
                  in={showTitle}
                  onEntering={elem => {
                    elem.style.transitionDelay = 200 * (index + lIndex *lineLetters.length) + 'ms';
                  }}
                >
                  <span>{letter}</span>
                </Fade>
              ))}
            </div>
          ))}
        </Typography>

        <div className={classes.listWrap}>
          <div className={classes.list}>

            <Dialog
              path="/question"
              fullScreen
              ignoreBackdropClick
              title={text.question.title}
              label={text.question.title}
            >
              <Question
                getQuestions={this.getQuestions}
                checkAnswer={this.checkAnswer}
                texts={text.question}
              />
            </Dialog>

            <Dialog
              path="/video-film"
              fullWidth
              nopadding
              title={text.film.title}
              label={text.film.title}
              onEntered={() => {this.filmVideo && this.filmVideo.play()}}
              onExit={() => {this.filmVideo && this.filmVideo.pause()}}
            >
              <video
                ref={elem => {this.filmVideo = elem}}
                className={classes.video}
                poster={filmThumbnail}
                src={videoFilm.src}
                playsInline
                controls
                preload={isCellular ? 'none' : 'auto'}
                autoPlay={false}
              />
            </Dialog>

            <Dialog
              path="/wiki"
              fullScreen
              ignoreBackdropClick
              title={text.wiki.title}
              label={text.wiki.title}
            >
              {wiki ? <Article content={wiki}/> : <LinearProgress/>}
            </Dialog>

            <Dialog
              path="/video-intro"
              nopadding
              fullWidth
              title={text.intro.title}
              label={text.intro.title}
              onEntered={() => {this.introVideo && this.introVideo.play()}}
              onExit={() => {this.introVideo && this.introVideo.pause()}}
            >
              <video
                ref={elem => {this.introVideo = elem}}
                className={classes.video}
                poster={introThumbnail}
                src={videoIntro.src}
                playsInline
                controls
                preload={isCellular ? 'none' : 'auto'}
                autoPlay={false}
              />
            </Dialog>
          </div>
        </div>
        <Confirm fullWidth maxWidth="sm"/>
        <Slide direction="up" in duration={500}>
          <CoverImage src={illustrator} sizing="contain" className={classes.illustrator}/>
        </Slide>
      </div>
    )
  }

}

export default App
